#!/bin/sh

E2E_OLM_VERSION="${E2E_OLM_VERSION:-0.28.0}"

. "$SPEC_PATH/dbops-security-upgrade"

e2e_test_extra_hash() {
  printf 'E2E_OLM_VERSION=%s\n' "$E2E_OLM_VERSION"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "stackgres-k8s/install/operator-sdk"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/metrics")"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/dbops-security-upgrade")"
}

e2e_skip_dbops_secutiry_upgrade() {
  [ "$(uname -m)" = "aarch64" ] || ! can_install_operator_version "$STACKGRES_PREVIOUS_VERSION"
}

e2e_load_images() {
  BUNDLE_STACKGRES_VERSION="$(printf %s "$STACKGRES_VERSION" | tr A-Z a-z)"
  BUNDLE_STACKGRES_PREVIOUS_VERSION="$(printf %s "$STACKGRES_PREVIOUS_VERSION" | tr A-Z a-z)"

  OPERATOR_BUNDLE_IMAGE_TAG_SUFFIX=""
  if [ "$E2E_ENV" = "minishift" ] || [ "$E2E_ENV" = "crc" ] || [ "$E2E_ENV" = "microshift" ]
  then
    OPERATOR_BUNDLE_IMAGE_TAG_SUFFIX="-openshift"
  fi
  OPERATOR_BUNDLE_IMAGE_TAG="${IMAGE_TAG%-jvm}$OPERATOR_BUNDLE_IMAGE_TAG_SUFFIX"
  OPERATOR_BUNDLE_IMAGE_TAG="$(printf %s "$OPERATOR_BUNDLE_IMAGE_TAG" | tr A-Z a-z)"

  OPERATOR_BUNDLE_PUBLIC_REGISTRY="${OPERATOR_BUNDLE_PUBLIC_REGISTRY:-quay.io}"
  OPERATOR_BUNDLE_PUBLIC_REGISTRY_PATH="${OPERATOR_BUNDLE_PUBLIC_REGISTRY_PATH:-/stackgres}"
  OPERATOR_BUNDLE_IMAGE_NAME="${OPERATOR_BUNDLE_PUBLIC_REGISTRY}${OPERATOR_BUNDLE_PUBLIC_REGISTRY_PATH}/operator-bundle:$OPERATOR_BUNDLE_IMAGE_TAG"
  OPERATOR_BUNDLE_CATALOG_IMAGE_NAME="${OPERATOR_BUNDLE_PUBLIC_REGISTRY}${OPERATOR_BUNDLE_PUBLIC_REGISTRY_PATH}/operator-catalog:$OPERATOR_BUNDLE_IMAGE_TAG"

  # The operator-registry check the bundle image from the remote repository
  BUNDLE_IMAGE_NAME="$E2E_OPERATOR_REGISTRY${E2E_OPERATOR_REGISTRY_PATH%/}/stackgres/${OPERATOR_BUNDLE_IMAGE_NAME##*/}"
  docker pull "$BUNDLE_IMAGE_NAME"
  mkdir -p "$LOG_PATH/operator-bundle"
  cat << EOF > "$LOG_PATH/operator-bundle.Dockerfile"
FROM "$BUNDLE_IMAGE_NAME" AS bundle

FROM debian AS overwrites
  COPY --from=bundle / /bundle
  RUN sed -i 's|^  name: .*$|  name: stackgres.v$BUNDLE_STACKGRES_VERSION|' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i 's|^  version: .*$|  version: $BUNDLE_STACKGRES_VERSION|' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i 's|^    containerImage: quay.io/stackgres/operator:.*$|    containerImage: $OPERATOR_IMAGE_NAME|' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i 's|^                    image: quay.io/stackgres/operator:.*$|                    image: $OPERATOR_IMAGE_NAME|' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i '/name: OPERATOR_VERSION$/{\$!{N;s/name: OPERATOR_VERSION\n\( *\)value: .*$/name: OPERATOR_VERSION\n\1value: "$STACKGRES_VERSION"/;ty;P;D;:y}}' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i '/name: OPERATOR_IMAGE_VERSION$/{\$!{N;s/name: OPERATOR_IMAGE_VERSION\n\( *\)value: .*$/name: OPERATOR_IMAGE_VERSION\n\1value: "$IMAGE_TAG"/;ty;P;D;:y}}' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i '/name: OPERATOR_JVM_IMAGE_VERSION$/{\$!{N;s/name: OPERATOR_JVM_IMAGE_VERSION\n\( *\)value: .*$/name: OPERATOR_JVM_IMAGE_VERSION\n\1value: "$NATIVE_IMAGE_TAG-jvm"/;ty;P;D;:y}}' /bundle/manifests/stackgres.clusterserviceversion.yaml
  RUN sed -i '/name: OPERATOR_NATIVE_IMAGE_VERSION$/{\$!{N;s/name: OPERATOR_NATIVE_IMAGE_VERSION\n\( *\)value: .*$/name: OPERATOR_NATIVE_IMAGE_VERSION\n\1value: "$NATIVE_IMAGE_TAG"/;ty;P;D;:y}}' /bundle/manifests/stackgres.clusterserviceversion.yaml

FROM scratch
  COPY --from=overwrites /bundle /
$(
    docker inspect "$BUNDLE_IMAGE_NAME" -f json \
      | jq -r '.[0].Config.Labels|to_entries|.[]|"LABEL \"" + .key + "\"=\"" + .value + "\""' \
      | sed 's/^/  /'
)
EOF
  BUNDLE_IMAGE_NAME="${BUNDLE_IMAGE_NAME}-overridden-$(date +%s)-$RANDOM"
  docker build -t "$BUNDLE_IMAGE_NAME" -f "$LOG_PATH/operator-bundle.Dockerfile" "$LOG_PATH/operator-bundle" 
  docker push "$BUNDLE_IMAGE_NAME"
}

e2e_install_previous_operator() {
  if [ "$E2E_ENV" != "minishift" ] && [ "$E2E_ENV" != "crc" ] && [ "$E2E_ENV" != "microshift" ]
  then
    e2e_properly_tag_not_found_import_images &
    trap_kill "$!"
    kubectl delete clusterrole system:controller:operator-lifecycle-manager 2>/dev/null \
      || ! kubectl get clusterrole system:controller:operator-lifecycle-manager 2>/dev/null
    wait_until eval '! kubectl get namespace olm > /dev/null 2>&1'
    operator-sdk olm install \
      --timeout "${E2E_TIMEOUT}s" \
      --version "$E2E_OLM_VERSION"
  fi

  if [ "$E2E_ENV" != "minishift" ] && [ "$E2E_ENV" != "crc" ] && [ "$E2E_ENV" != "microshift" ]
  then
    PREVIOUS_BUNDLE_IMAGE_NAME="$(wait_until eval \
      'kubectl exec -n olm "$(kubectl get pod -n olm -l olm.catalogSource=operatorhubio-catalog -o name | grep "^pod/")" \
      -- cat configs/stackgres/catalog.yaml \
      | yq -sr ".[]|select(.name == \"stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION\").image" | grep .')"
  else
    PREVIOUS_BUNDLE_IMAGE_NAME="$(wait_until eval \
      'kubectl exec -n openshift-marketplace "$(kubectl get pod -n openshift-marketplace -l olm.catalogSource=redhat-marketplace -o name | grep "^pod/")" \
      -- cat /configs/stackgres/catalog.json \
      | jq -sr ".[]|select(.name == \"stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION\").image" | grep .')"
  fi

  CATALOG_IMAGE_NAME="${E2E_CATALOG_IMAGE_REGISTRY:-$E2E_OPERATOR_REGISTRY${E2E_OPERATOR_REGISTRY_PATH%/}}/stackgres/${OPERATOR_BUNDLE_CATALOG_IMAGE_NAME##*/}"
  mkdir -p "$LOG_PATH/operator-catalog"
  opm generate dockerfile "$LOG_PATH/operator-catalog"
  echo > "$LOG_PATH/README.md"
  opm init stackgres \
    --default-channel=stable \
    --description="$LOG_PATH/README.md" \
    --output yaml > "$LOG_PATH/operator-catalog/operator.yaml"
  opm render "$PREVIOUS_BUNDLE_IMAGE_NAME" \
    --output=yaml >> "$LOG_PATH/operator-catalog/operator.yaml"
  opm render "$BUNDLE_IMAGE_NAME" \
    --output=yaml >> "$LOG_PATH/operator-catalog/operator.yaml"
  cat << EOF >> "$LOG_PATH/operator-catalog/operator.yaml"
---
schema: olm.channel
package: stackgres
name: stable
entries:
  - name: stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION
  - name: stackgres.v$BUNDLE_STACKGRES_VERSION
    replaces: stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION
EOF
  sed -i "s/^name: stackgres.v${BUNDLE_STACKGRES_VERSION%-*}.*$/name: stackgres.v$BUNDLE_STACKGRES_VERSION/" "$LOG_PATH/operator-catalog/operator.yaml"
  sed -i "s/^    version: ${BUNDLE_STACKGRES_VERSION%-*}.*$/    version: $BUNDLE_STACKGRES_VERSION/" "$LOG_PATH/operator-catalog/operator.yaml"
  sed -i "s/^- image: \([^:]\+\):${BUNDLE_STACKGRES_VERSION%-*}.*$/- image: \1:$BUNDLE_STACKGRES_VERSION/" "$LOG_PATH/operator-catalog/operator.yaml"
  opm validate "$LOG_PATH/operator-catalog"
  (
  cd "$LOG_PATH"
  docker build . \
    -f "operator-catalog.Dockerfile" \
    -t "$CATALOG_IMAGE_NAME"
  )
  docker push "$CATALOG_IMAGE_NAME"

  if [ "$E2E_SKIP_LOAD_OPERATOR_BUNDLE" != true ]
  then
    if [ "$E2E_FORCE_IMAGE_PULL" = "true" ]
    then
      echo "Loading operator images from $E2E_OPERATOR_REGISTRY$E2E_OPERATOR_REGISTRY_PATH"
      e2e_load_operator_images_from "$E2E_OPERATOR_REGISTRY" "$E2E_OPERATOR_REGISTRY_PATH"
    fi
    IMAGES="$(e2e_get_operator_images "$STACKGRES_VERSION")"
    for IMAGE in $IMAGES
    do
      docker_tag "$IMAGE" "${IMAGE%:*}:$(printf %s "$STACKGRES_VERSION$OPERATOR_BUNDLE_IMAGE_TAG_SUFFIX" | tr A-Z a-z)"
    done
    OPERATOR_IMAGES="$(get_operator_images "$STACKGRES_VERSION")"
    for IMAGE in $OPERATOR_IMAGES
    do
      docker_tag "$IMAGE" "${IMAGE%:*}:$BUNDLE_STACKGRES_VERSION"
    done
    echo "All operator images loaded from $E2E_OPERATOR_REGISTRY$E2E_OPERATOR_REGISTRY_PATH"
  fi

  OPERATOR_NAMESPACE="$(generate_operator_namespace)"
  kubectl create namespace "${OPERATOR_NAMESPACE}"
  kubectl label namespace "$OPERATOR_NAMESPACE" --overwrite monitoring=true

  cat << EOF > "$LOG_PATH/operator-catalog-source.yaml"
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: operator-catalog
  namespace: $OPERATOR_NAMESPACE
spec:
  sourceType: grpc
  image: $CATALOG_IMAGE_NAME
  displayName: Helm Operator Catalog
  publisher: OnGres
  updateStrategy:
    registryPoll:
      interval: 10m
EOF
  kubectl create -f "$LOG_PATH/operator-catalog-source.yaml"

  echo "Installing previous version of operator bundle ($STACKGRES_PREVIOUS_VERSION)"
  cat << EOF > "$LOG_PATH/stackgres-operator-group.yaml"
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: stackgres
  namespace: $OPERATOR_NAMESPACE
spec:
$(
  if [ "x$E2E_ALLOWED_NAMESPACES" != x ]
  then
    cat << INNER_EOF
  targetNamespaces:
$(printf %s "$E2E_ALLOWED_NAMESPACES" | tr ' ' '\n' | sed 's/^/  - /')
INNER_EOF
    if ! printf ' %s ' "$E2E_ALLOWED_NAMESPACES" | grep -qF " $OPERATOR_NAMESPACE "
    then
      printf '  - %s\n' "$OPERATOR_NAMESPACE"
    fi
  fi
)
EOF
  kubectl create -f "$LOG_PATH/stackgres-operator-group.yaml"
  cat << EOF > "$LOG_PATH/stackgres-subscription-$STACKGRES_PREVIOUS_VERSION.yaml"
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: stackgres
  namespace: $OPERATOR_NAMESPACE
spec:
  channel: stable
  name: stackgres
  source: operator-catalog
  sourceNamespace: $OPERATOR_NAMESPACE
  installPlanApproval: Manual
  startingCSV: stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION
EOF
  kubectl create -f "$LOG_PATH/stackgres-subscription-$STACKGRES_PREVIOUS_VERSION.yaml"
  INSTALL_PLAN="$(wait_until eval 'kubectl get installplan -n "$OPERATOR_NAMESPACE" \
    --template "{{ range .items }}{{ if and .status (eq (index .spec.clusterServiceVersionNames 0) \"stackgres.v$BUNDLE_STACKGRES_PREVIOUS_VERSION\") }}{{ printf \"%s\n\" .metadata.name }}{{ end }}{{ end }}" \
    | grep .')"
  kubectl patch -n "$OPERATOR_NAMESPACE" installplan "$INSTALL_PLAN" --type merge -p '{"spec":{"approved":true}}'

  if ! wait_until -t "$((E2E_TIMEOUT * 4))" eval 'kubectl get sgconfig -A -o name | wc -l | grep -qxF 1'
  then
    fail "The StackGres SGConfig was not found."
  else
    success "The StackGres SGConfig was found."
  fi

  PREVIOUS_RELEASE_NAME="$(kubectl get sgconfig -n "$OPERATOR_NAMESPACE" -o name | grep "^sgconfig.stackgres.io/")"
  PREVIOUS_RELEASE_NAME="${PREVIOUS_RELEASE_NAME#*/}"
  if [ "$STACKGRES_PREVIOUS_VERSION" != 1.11.0 ] && [ "$STACKGRES_PREVIOUS_VERSION" != 1.12.0 ]
  then
    kubectl patch -n "$OPERATOR_NAMESPACE" sgconfig "$PREVIOUS_RELEASE_NAME" --type merge \
      -p '{"spec":{"grafana":{"autoEmbed": true, "webHost":"'"prometheus-grafana.$(prometheus_namespace)"'"}}}'
  fi

  if ! wait_services_available "$OPERATOR_NAMESPACE" 1 "^$PREVIOUS_RELEASE_NAME$"
  then
    fail "The StackGres operator service was not available."
  else
    success "The StackGres operator service was available."
  fi

  if ! wait_services_available "$OPERATOR_NAMESPACE" 1 "^stackgres-restapi$"
  then
    fail "The StackGres restapi service was not available."
  else
    success "The StackGres restapi service was available."
  fi

  if [ "$(kubectl get sgconfig -n "$OPERATOR_NAMESPACE" stackgres-operator -o json | jq .spec.extensions.cache.enabled)" = true ]
  then
    if ! wait_services_available "$OPERATOR_NAMESPACE" 1 "^stackgres-operator-extensions-cache$"
    then
      fail "The demo StackGres extensions cache service was not available."
    else
      success "The demo StackGres extensions cache service was available."
    fi
  fi
}

e2e_upgrade_operator() {
  SGCONFIG_NAMESPACE="$OPERATOR_NAMESPACE"
  if [ "x$E2E_ALLOWED_NAMESPACES" != x ] \
    && ! printf ' %s ' "$E2E_ALLOWED_NAMESPACES" | grep -qF " $OPERATOR_NAMESPACE "
  then
    SGCONFIG_NAMESPACE="$CLUSTER_NAMESPACE"
  fi

  echo "Upgrading operator bundle ($STACKGRES_VERSION)"

  # The operator-sdk does not allow to load a bundle with IfNotPresent so we have to pull it from the remote repository
  BUNDLE_IMAGE_NAME="$E2E_OPERATOR_REGISTRY${E2E_OPERATOR_REGISTRY_PATH%/}/stackgres/${OPERATOR_BUNDLE_IMAGE_NAME##*/}"
  kubectl create secret docker-registry -n "$OPERATOR_NAMESPACE" operator-bundle \
    --from-file=.dockerconfigjson="$HOME"/.docker/config.json

  INSTALL_PLAN="$(wait_until eval 'kubectl get installplan -n "$OPERATOR_NAMESPACE" -o json \
    | jq -r ".items[]|select(.status != null and (.spec.clusterServiceVersionNames[0] | gsub(\"-.*\";\"\")) == \"stackgres.v${BUNDLE_STACKGRES_VERSION%-*}\").metadata.name" \
    | grep .')"
  kubectl patch -n "$OPERATOR_NAMESPACE" installplan "$INSTALL_PLAN" --type merge -p '{"spec":{"approved":true}}'

  wait_until eval 'kubectl get -n "$OPERATOR_NAMESPACE" deployment -l olm.owner="stackgres.v$BUNDLE_STACKGRES_VERSION" -o name | grep -q .'

  cat << EOF > "$LOG_PATH/sgconfig-patch.yaml"
apiVersion: stackgres.io/v1
kind: SGConfig
spec:
  operator:
    image:
      tag: "$IMAGE_TAG"
  restapi:
    image:
      tag: "$IMAGE_TAG"
  adminui:
    image:
      tag: "$ADMINUI_IMAGE_TAG"
  developer:
    version: $STACKGRES_VERSION
$(
  if [ -n "$E2E_EXTRA_MOUNT_BUILD_PATH" ]
  then
    cat << INNER_EOF
    patches:
      restapi:
        volumes:
          - name: app
            hostPath:
              path: "$(realpath "$E2E_EXTRA_MOUNT_BUILD_PATH"/stackgres-k8s/src/restapi/target/quarkus-app)"
        volumeMounts:
          - name: app
            mountPath: /app/app
            subPath: app
          - name: app
            mountPath: /app/lib
            subPath: lib
          - name: app
            mountPath: /app/quarkus
            subPath: quarkus
          - name: app
            mountPath: /app/quarkus-run.jar
            subPath: quarkus-run.jar
      adminui:
        volumes:
          - name: admin
            hostPath:
              path: "$(realpath "$E2E_EXTRA_MOUNT_BUILD_PATH"/stackgres-k8s/src/admin-ui/target/public)"
        volumeMounts:
          - name: admin
            mountPath: /opt/app-root/src/admin
      clusterController:
        volumes:
          - name: app
            hostPath:
              path: "$(realpath "$E2E_EXTRA_MOUNT_BUILD_PATH"/stackgres-k8s/src/cluster-controller/target/quarkus-app)"
        volumeMounts:
          - name: app
            mountPath: /app/app
            subPath: app
          - name: app
            mountPath: /app/lib
            subPath: lib
          - name: app
            mountPath: /app/quarkus
            subPath: quarkus
          - name: app
            mountPath: /app/quarkus-run.jar
            subPath: quarkus-run.jar
INNER_EOF
  fi
)
EOF

  EXTRA_OPTS="$(printf %s "
        -Dquarkus.log.category.\"io.stackgres\".level=DEBUG 
        -Dquarkus.log.category.\"io.quarkus\".level=INFO 
        -Dquarkus.log.category.\"io.stackgres.dbops\".level=TRACE 
        -Dquarkus.log.category.\"io.stackgres.backup\".level=TRACE 
        -Dquarkus.log.category.\"io.stackgres.wal-g\".level=INFO 
        -Dquarkus.log.category.\"io.stackgres.patroni\".level=TRACE 
        -Dquarkus.log.category.\"io.stackgres.fluent-bit\".level=TRACE 
        -Dquarkus.log.category.\"io.stackgres.fluentd\".level=TRACE 
        -Dquarkus.log.category.\"io.stackgres.prometheus-postgres-exporter\".level=TRACE 
        -Dquarkus.log.category.\"okhttp3.logging.HttpLoggingInterceptor\".level=$(
          # shellcheck disable=SC2015
          [ "$E2E_LOG_OPERATOR_HTTP" = true ] && echo TRACE || echo INFO) 
        -Dquarkus.log.category.\"stackgres-extensions-cache\".level=DEBUG 
        -Dquarkus.log.category.\"io.stackgres.operator.conciliation\".level=TRACE 
    " | tr -s ' \n' ' ' | jq -s -R .)"

  cat << EOF > "$LOG_PATH/subscription-patch.yaml"
{
  "spec": {
    "config": {
      "resources": {},
      "env":[
        {"name":"SG_IMAGE_CLUSTER_CONTROLLER","value":"${CLUSTER_CONTROLLER_IMAGE_NAME}"},
        {"name":"JAVA_OPTS","value":$EXTRA_OPTS},
        {"name":"APP_OPTS","value":$EXTRA_OPTS},
        {"name":"SGCONFIG","value":$(yq --arg sgconfig "${E2E_OPERATOR_BUNDLE_SGCONFIG:-{\}}" '($sgconfig | fromjson) * . | tostring' "$LOG_PATH/sgconfig-patch.yaml")}
$(
  if [ "x$E2E_ALLOWED_NAMESPACES" != x ] \
    && ! printf ' %s ' "$E2E_ALLOWED_NAMESPACES" | grep -qF " $OPERATOR_NAMESPACE "
  then
    cat << INNER_EOF
        ,
        {"name":"SGCONFIG_NAMESPACE","value":"$CLUSTER_NAMESPACE"}
INNER_EOF
  fi
)
      ]
$(
  if [ -n "$E2E_EXTRA_MOUNT_BUILD_PATH" ]
  then
    cat << INNER_EOF
      ,
      "volumes":[
        {"name":"app","hostPath":{"path":"$(realpath "$E2E_EXTRA_MOUNT_BUILD_PATH"/stackgres-k8s/src/operator/target/quarkus-app)"}}],
      "volumeMounts":[
        {"name":"app","mountPath":"/app/app","subPath":"app"},
        {"name":"app","mountPath":"/app/lib","subPath":"lib"},
        {"name":"app","mountPath":"/app/quarkus","subPath":"quarkus"},
        {"name":"app","mountPath":"/app/quarkus-run.jar","subPath":"quarkus-run.jar"}]
INNER_EOF
  fi
)
    }
  }
}
EOF

  kubectl patch -n "$OPERATOR_NAMESPACE" subscription stackgres --type merge --patch-file "$LOG_PATH/subscription-patch.yaml"

  wait_until eval 'kubectl get pod -n "$OPERATOR_NAMESPACE" -l app=stackgres-operator \
    --template "{{ range .items }}{{ range .spec.containers }}{{ printf \"%s\n\" .image }}{{ end }}{{ end }}" \
    | grep -qF "'"/${EXPECTED_OPERATOR_IMAGE##*/}"'"'

  wait_until -t "$((E2E_TIMEOUT * 3))" eval 'kubectl get pod -n "$OPERATOR_NAMESPACE" -l app=stackgres-operator -o name | wc -l | grep -xF 1'

  wait_until kubectl rollout status --timeout=1s -n "$OPERATOR_NAMESPACE" deployment -l olm.owner="stackgres.v$BUNDLE_STACKGRES_VERSION"

  wait_until eval 'kubectl get pod -n "$SGCONFIG_NAMESPACE" -l app=StackGresConfig,stackgres.io/restapi=true \
    --template "{{ range .items }}{{ range .spec.containers }}{{ printf \"%s\n\" .image }}{{ end }}{{ end }}" \
    | grep -qF "'"/${EXPECTED_RESTAPI_IMAGE##*/}"'"'

  wait_until eval 'kubectl get pod -n "$SGCONFIG_NAMESPACE" -l app=StackGresConfig,stackgres.io/restapi=true -o name | wc -l | grep -xF 1'

  if [ "$STACKGRES_PREVIOUS_VERSION" = 1.11.0 ] || [ "$STACKGRES_PREVIOUS_VERSION" = 1.12.0 ]
  then
    RELEASE_NAME="$(kubectl get sgconfig -n "$OPERATOR_NAMESPACE" -o name | grep "^sgconfig.stackgres.io/")"
    RELEASE_NAME="${RELEASE_NAME#*/}"
    kubectl patch -n "$OPERATOR_NAMESPACE" sgconfig "$RELEASE_NAME" --type merge \
      -p '{"spec":{"grafana":{"autoEmbed": true, "webHost":"'"prometheus-grafana.$(prometheus_namespace)"'"}}}'
  fi

  if ! wait_services_available "$OPERATOR_NAMESPACE" 1 "^stackgres-operator$"
  then
    fail "The StackGres operator service was not available."
  else
    success "The StackGres operator service was available."
  fi

  if ! wait_services_available "$SGCONFIG_NAMESPACE" 1 "^stackgres-restapi$"
  then
    fail "The StackGres restapi service was not available."
  else
    success "The StackGres restapi service was available."
  fi

  if ! wait_until eval 'kubectl get job -n "$SGCONFIG_NAMESPACE" -l "app=StackGresConfig" -o name | wc -l | grep -qxF 0'
  then
    fail "The StackGres jobs still running."
  else
    success "The StackGres jobs all cleaned up."
  fi

  if [ "$(kubectl get sgconfig -n "$SGCONFIG_NAMESPACE" stackgres-operator -o json | jq .spec.extensions.cache.enabled)" = true ]
  then
    if ! wait_services_available "$SGCONFIG_NAMESPACE" 1 "^stackgres-operator-extensions-cache$"
    then
      fail "The demo StackGres extensions cache service was not available."
    else
      success "The demo StackGres extensions cache service was available."
    fi
  fi

  local PASSWORD
  PASSWORD="$(kubectl get sgconfig -n "$SGCONFIG_NAMESPACE" stackgres-operator -o json \
    | jq -r '.spec.authentication.password | select(. != null)' | tr -d '\n')"
  if [ -n "$PASSWORD" ]
  then
    kubectl patch secret -n "$SGCONFIG_NAMESPACE" stackgres-restapi-admin -p '{"data":{"password":null,"clearPassword":"'"$(printf '%s' "$PASSWORD" | base64)"'"}}'
  fi
}

e2e_load_operator_images_from() {
  local REPOSITORY="${1:-$OPERATOR_BUNDLE_PUBLIC_REGISTRY}"
  local IMAGE_PATH="${2:-$OPERATOR_BUNDLE_PUBLIC_REGISTRY_PATH}"
  local VERSION="${3:-$STACKGRES_VERSION}"
  local IMAGES
  IMAGES="$(e2e_get_operator_images "$VERSION")"
  printf '%s' "$IMAGES" \
    | xargs_parallel_shell % "$E2E_PATH/e2e" \
      pull_image_from "$REPOSITORY" "${IMAGE_PATH%/}/stackgres" "%"
}

e2e_get_operator_images() {
  [ -n "$1" ]
  local VERSION="$1"
  local NATIVE_TAG="$VERSION"
  if [ "$VERSION" = "$STACKGRES_VERSION" ]
  then
    NATIVE_TAG="${IMAGE_TAG%-jvm}"
  fi
  local TAG="$NATIVE_TAG-jvm"
  if [ "$VERSION" = "$STACKGRES_VERSION" ] \
    && [ "${IMAGE_TAG%-jvm}" = "$IMAGE_TAG" ]
  then
    TAG="$NATIVE_TAG"
  fi
  echo "${OPERATOR_BUNDLE_IMAGE_NAME%:*}:$NATIVE_TAG"
}

e2e_properly_tag_not_found_import_images() {
  echo "Looking for import-* images to tag properly"
  event_watch  --follow \
    | stdbuf -o0 grep '\simage "\(.*library/import-[^@]\+@sha256:[^"]\+\)": not found' \
    | stdbuf -o0 sed 's#^.*\simage "\(.*library/import-[^@]\+@sha256:[^"]\+\)": not found.*$#\1#' \
    | (
      while read IMAGE_NAME
      do
        echo "Detected import-* image $IMAGE_NAME to tag properly into k8s env $E2E_ENV"
        tag_image_k8s "${IMAGE_NAME#*library/}" "$IMAGE_NAME"
      done
      )
}

e2e_cleanup() {
  ! kubectl get sgconfig || kubectl delete sgconfig -A --all --wait
  k8s_unnamespaced_cleanup
  k8s_cleanup_namespace "$OPERATOR_NAMESPACE"
  k8s_async_cleanup || true
}

check_conversion_webhooks_configured(){
  CONVERSTION_STRATEGY="$(kubectl get crd sgclusters.stackgres.io -o jsonpath='{.spec.conversion.strategy}')"

  assert_string_equal "None" "$CONVERSTION_STRATEGY"

  CONVERSTION_STRATEGY="$(kubectl get crd sgdistributedlogs.stackgres.io -o jsonpath='{.spec.conversion.strategy}')"

  assert_string_equal "None" "$CONVERSTION_STRATEGY"
}
